'use strict';
const Request = require('request');
const jsSHA = require('jssha');//1.5.0版本
const wechatOauth = require('wechat-oauth');//微信授权

module.exports = function(config,memcached){

    var WxApi = function(config){//微信类
        this.appId = config.appId;
        this.appSecret = config.appSecret;
        this.cachepath = config.cachepath;//缓存路径
    }

    var Store = function(memcached){//缓存类
        this._conn = memcached;
    }

    var self = new WxApi(config);
    var store = new Store(memcached);
    var oauth = new wechatOauth(self.appId,self.appSecret);

    //外部接口
    var _outInterface = {};
    _outInterface.getToken = function(){//获取token
        return new Promise((resolve,reject)=>{
            Request.post(
                {
                    url:'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential',
                    form:{
                        appid:self.appId,
                        secret:self.appSecret
                    },
                    encoding:'utf8'
                },
                function(error, response, body){
                    if(response.statusCode == 200){
                        var outObj = JSON.parse(body);
                        resolve(outObj.access_token);
                    }else{
                        resolve(false);
                    }
                }
            );
        });
    }

    _outInterface.getTicket = function(token){//获取签名
        return new Promise((resolve,reject)=>{
            Request.post(
                {
                    url:'https://api.weixin.qq.com/cgi-bin/ticket/getticket?&type=jsapi',
                    form:{
                        access_token:token
                    },
                    encoding:'utf8'
                },
                function(error,response,body){
                    if(response.statusCode == 200){
                        var outObj = JSON.parse(body);
                        resolve(outObj.ticket);
                    }else{
                        resolve(false);
                    }
                }
            );
        });
    }

    //常规接口
    var _core = {};

    _core.createNonceStr = function () {
      return Math.random().toString(36).substr(2, 15);
    };

    _core.createTimestamp = function () {
      return parseInt(new Date().getTime() / 1000) + '';
    };

    _core.raw = function (args) {
      var keys = Object.keys(args);
      keys = keys.sort()
      var newArgs = {};
      keys.forEach(function (key) {
        newArgs[key.toLowerCase()] = args[key];
      });

      var string = '';
      for (var k in newArgs) {
        string += '&' + k + '=' + newArgs[k];
      }
      string = string.substr(1);
      return string;
    };

    _core.sign = function(jsapi_ticket,url){//签名算法
      var ret = {
        jsapi_ticket: jsapi_ticket,
        nonceStr: _core.createNonceStr(),
        timestamp: _core.createTimestamp(),
        url: url
      };
      try{
          var string = _core.raw(ret);
          var shaObj = new jsSHA(string, 'TEXT');
          ret.signature = shaObj.getHash('SHA-1', 'HEX');
      }catch(err){
        console.log(err);
      }
      return ret;
    }

    WxApi.prototype.oauth = oauth;

    //获取token
    WxApi.prototype.getToken = function (){
        return new Promise((resolve,reject)=>{
            store.get(self.cachepath).then(cachetoken=>{
                if(!cachetoken){//无缓存
                    _outInterface.getToken().then(token=>{
                        if(token){
                            store.set(self.cachepath,token,7140);
                            resolve(token);
                        }else{
                            resolve(false);
                        }
                    });
                }else{//有缓存
                    resolve(cachetoken);
                }
            });            
        });
    }

    //获取ticket
    WxApi.prototype.getTicket = function(){
        return new Promise((resolve,reject)=>{
            self.getToken().then(token=>{
                if(token){
                    _outInterface.getTicket(token).then(ticket=>{
                        if(ticket){
                            resolve(ticket);
                        }else{
                            resolve(false);
                        }
                    });
                }else{
                    resolve(false);
                }
            });
        });
    }

    //签名
    WxApi.prototype.sign = function(url){
        return new Promise((resolve,reject)=>{
            self.getTicket(url).then(ticket=>{
                if(ticket){
                    resolve(_core.sign(ticket,url));
                }else{
                    resolve(false);
                }
            });
        });
    }
    
    //插入缓存
    Store.prototype.set = function(keyname,val,time){
        var _this = this;
        return new Promise((resolve,reject)=>{
            if(_this._conn){
                _this.get(keyname).then(cacheval=>{
                    if(!cacheval){//添加新缓存
                        console.log('_conn-add');
                        _this._conn.add(keyname,val,time,function(err,data){
                            if(err){
                                console.log('add error:',err);
                                return resolve(false);  
                            }
                            console.log('add success:',data);
                            return resolve(true)
                        });
                    }else{//刷新缓存
                        console.log('_conn-replace');
                         _this._conn.replace(keyname,val,time,function(err,data){
                            if(err){
                                console.log('add error:',err);
                                return resolve(false);  
                            }
                            console.log('add success:',data);
                            return resolve(true)
                        });
                    }                   
                });
            }else{
                cache.set(keyname,val,null,(err)=>{
                    cache.get(keyname, (err, value, cached, log) => {
                        if(val==value){
                            return resolve(true);                    
                        }else{
                            return resolve(false);  
                        }
                    });
                });
            }
        });
    }

    //读取缓存
    Store.prototype.get = function (keyname){
        var _this = this;
        return new Promise((resolve,reject)=>{
            if(_this._conn){
                _this._conn.get(keyname,function(err,data){
                    if(err){
                        console.log('get error:',err);
                        _this._conn.end();
                        return resolve(false);
                    }
                    console.log('get success',data);
                    return typeof(data)!='undefined'?resolve(data):resolve(false);                
                });                
            }else{
                cache.get(keyname, (err, value, cached, log) => {
                    return resolve(value);                    
                });
            }
        });
    }

    var wxApi = self;

	return wxApi;
}